#include "project.h"
#include <thread>
#include <memory>

static const int GRID_ROWS = 2;
static const int GRID_COLS = 4;
static const int THUMBNAIL_WIDTH = 256;   // 1024 / 4
static const int THUMBNAIL_HEIGHT = 300;  // 600 / 2
// ------------------------------ Album类实现 ------------------------------
bool Album::addPhoto(const std::string& path) {
    std::cout << "=== addPhoto: 尝试添加 " << path << " ===" << std::endl;

    if (access(path.c_str(), R_OK) != 0) {
        std::cerr << "文件不可读或不存在: " << path << std::endl;
        return false;
    }

    photo_paths->push_back(path);
    if (!has_photos) {
        has_photos = true;
        present_photo_index = 0;  // 第一张，索引为 0
    }
    // 否则保持当前索引不变
    return true;
}
// bool Album::addPhoto(string photo_path)
// {
//   if(access(photo_path.c_str(), F_OK) != 0)
//   {
//     cerr << "图片不存在：" << photo_path << endl;
//     return false;
//   }  
//   //lock_guard<mutex> lock(album_mtx); // 加锁保护容器操作
//   this->photo_paths->push_back(photo_path);
//   if (!has_photos) {
//     has_photos = true;
//     present_photo = photo_paths->begin(); // ✅ 安全：此时 vector 已包含元素
//   }
//   // if(this->findPhoto(photo_path) != this->photo_paths->end())
//   // {
//   //   return false;
//   // }

//   // this->has_photos = !this->photo_paths->empty();
//   // if(this->photo_paths->size() == 1)
//   // {
//   //   this->present_photo = this->photo_paths->begin();
//   // }
//   return true;
// }
bool Album::deletePhoto(const std::string& photo_path)
{
    std::lock_guard<std::mutex> lock(album_mtx);

    // 找到要删除的元素的索引
    auto it = findPhoto(photo_path);
    if (it == photo_paths->end()) {
        return false;
    }

    size_t deleted_index = std::distance(photo_paths->begin(), it);
    bool is_current_photo = (deleted_index == present_photo_index);

    // 执行删除
    photo_paths->erase(it);
    has_photos = !photo_paths->empty();

    if (is_current_photo && has_photos) {
        // 更新当前显示的图片索引
        if (present_photo_index >= photo_paths->size()) {
            present_photo_index = 0;  // 删除的是最后一张或越界
        }
        // 否则保持 present_photo_index 不变（后面的元素前移，index 自动指向下一张）
        is_zoomed = false;

        if (lcd) {
            lcd->clearScreen();
            const std::string& new_path = (*photo_paths)[present_photo_index];
            lcd->display_bmp(new_path.c_str());
        }
    }
    else if (!has_photos) {
        // 没有图片了，清屏
        if (lcd) {
            lcd->clearScreen();
        }
    }

    return true;
}

vector<string>::iterator Album::findPhoto(string photo_path)
{
  return find(this->photo_paths->begin(), this->photo_paths->end(), photo_path);
}
bool Album::displayPhoto()
{
    std::cout << "进入 displayPhoto" << std::endl;
    std::lock_guard<std::mutex> lock(album_mtx);
    std::cout << "获取锁成功" << std::endl;

    if (!has_photos || photo_paths->empty()) {
        std::cerr << "没有图片可显示" << std::endl;
        return false;
    }

    if (present_photo_index >= photo_paths->size()) {
        std::cerr << "索引越界: " << present_photo_index << std::endl;
        return false;
    }

    const std::string& path = (*photo_paths)[present_photo_index];
    std::cout << "✅ 当前图片: " << path << std::endl;

    if (!lcd) return false;
    this->lcd->clearScreen();
    return this->lcd->display_bmp(path.c_str());
}


// 实现双击放大、单击缩小的点击事件处理
void Album::onTouchClick(int x, int y) {
   // std::lock_guard<std::mutex> lock(album_mtx);

    auto now = std::chrono::steady_clock::now();

    // ✅ 替代方案：使用 shared_from_this() 构造 weak_ptr
    try {
        // 先尝试获取 shared_ptr（必须在 shared_ptr 管理下才能调用）
        std::shared_ptr<Album> shared_this = shared_from_this();
        std::weak_ptr<Album> weak_this = shared_this; // ✅ 自动转换

        // 现在可以继续使用 weak_this
        last_click_x = x;
        last_click_y = y;
        last_touch_time = now;

        bool is_time_double_click = (now - last_touch_time) <= 
                                    std::chrono::milliseconds(DOUBLE_CLICK_INTERVAL);
        bool is_distance_valid = (std::abs(x - last_click_x) <= DOUBLE_CLICK_DISTANCE) &&
                                 (std::abs(y - last_click_y) <= DOUBLE_CLICK_DISTANCE);

        if (is_time_double_click && is_distance_valid) {
            if (!is_zoomed) {
                displayZoomedPhoto();
                is_zoomed = true;
            } else {
                is_zoomed = false;
                displayPhoto();
            }
        } else {
            // 单击逻辑：延迟判断
            std::thread([weak_this, x, y]() {
                std::this_thread::sleep_for(std::chrono::milliseconds(DOUBLE_CLICK_INTERVAL + 50));
                auto locked = weak_this.lock();
                if (locked) {
                    std::lock_guard<std::mutex> lock_inner(locked->album_mtx);
                    if (!locked->is_zoomed) {
                        std::cout << "单击触发: (" << x << ", " << y << ")" << std::endl;
                        // 执行单击操作
                    }
                }
            }).detach();
        }

    } catch (const std::bad_weak_ptr& e) {
        // 如果 Album 不是通过 shared_ptr 构造的，shared_from_this() 会抛异常
        std::cerr << "Album not managed by shared_ptr!" << std::endl;
        return;
    }

    cout << "进入 onTouchClick" << endl;
}


void Album::onTouchSwipe(int direction)
{
  //lock_guard<mutex> lock(album_mtx);
  if(this->photo_paths->empty()) return;

  if(is_zoomed)
  {
    return;
  }

  switch(direction)
  {
    case SWIPE_LEFT:
      this->nextPhoto();
      this->displayPhoto();
      break;
    case SWIPE_RIGHT:
      this->prevPhoto();
      this->displayPhoto();
      break;
    case SWIPE_UP:
      this->displayThumbnailGrid();
      break;
    case SWIPE_DOWN:
      this->displayScaledDownPhoto();
    default:
      break;
  }
  cout << "onTouchswipe" << endl;
}


void Album::nextPhoto()
{
    std::lock_guard<std::mutex> lock(album_mtx); // 加锁保护共享数据

    if (!has_photos || photo_paths->empty()) {
        return;
    }

    // 当前索引 +1，循环到开头
    present_photo_index++;
    if (present_photo_index >= photo_paths->size()) {
        present_photo_index = 0; // 循环：最后一张之后回到第一张
    }

    cout << "下一张" << endl;
    is_zoomed = false; // 切换图片时取消缩放

    if (lcd) {
        lcd->clearScreen();
        const std::string& path = (*photo_paths)[present_photo_index];
        lcd->display_bmp(path.c_str());
    }
}


void Album::prevPhoto()
{
    std::lock_guard<std::mutex> lock(album_mtx); // 加锁保护

    if (!has_photos || photo_paths->empty()) {
        return;
    }

    // 当前索引 -1，循环到最后一张
    if (present_photo_index == 0) {
        present_photo_index = photo_paths->size() - 1; // 回到最后一张
    } else {
        present_photo_index--; // 正常前移
    }
    is_zoomed = false; // 取消缩放

    if (lcd) {
        lcd->clearScreen();
        const std::string& path = (*photo_paths)[present_photo_index];
        lcd->display_bmp(path.c_str());
    }
}


void Album::displayZoomedPhoto() {
    std::cout << "[DEBUG] displayZoomedPhoto 调用，路径: "  << std::endl;
    std::lock_guard<std::mutex> lock(album_mtx); // 加锁保护共享数据

    // ✅ 安全检查：是否有图片 + 索引是否越界 + LCD 是否就绪
    if (!has_photos || 
        photo_paths->empty() || 
        present_photo_index >= photo_paths->size() ||
        lcd == nullptr || 
        lcd->mmap_start == nullptr || 
        lcd->mmap_start == (int*)MAP_FAILED) {
        return;
    }

    // ✅ 使用索引安全访问路径
    const std::string& photo_path = (*photo_paths)[present_photo_index];
    const char* bmp_path = photo_path.c_str();

    int bmp_fd = open(bmp_path, O_RDONLY);
    if (bmp_fd == -1) {
        std::cerr << "打开放大图片失败: " << strerror(errno) << " (" << bmp_path << ")" << std::endl;
        return;
    }

    // -------------------------- 步骤1：读取BMP图片基本信息 --------------------------
    // 读取宽度和高度
    int bmp_width = 0;
    int original_bmp_height = 0;
    if (lseek(bmp_fd, 18, SEEK_SET) == -1 ||
        read(bmp_fd, &bmp_width, 4) != 4 ||
        read(bmp_fd, &original_bmp_height, 4) != 4) {
        std::cerr << "读取尺寸失败" << std::endl;
        close(bmp_fd);
        return;
    }

    int bmp_height = std::abs(original_bmp_height);
    bool is_bottom_up = (original_bmp_height > 0); // 正数表示 bottom-up，需要翻转

    // 计算行对齐补位
    int pixel_bytes_per_row = bmp_width * 3;
    int bmp_skip = (4 - (pixel_bytes_per_row) % 4) % 4;
    int bmp_line_bytes = pixel_bytes_per_row + bmp_skip;
    size_t total_pixels_size = static_cast<size_t>(bmp_line_bytes) * bmp_height;

    // 移动到像素数据区
    if (lseek(bmp_fd, 54, SEEK_SET) == -1) {
        std::cerr << "无法定位到BMP像素数据" << std::endl;
        close(bmp_fd);
        return;
    }

    // 分配内存并读取像素
    char* bmp_pixels = new (std::nothrow) char[total_pixels_size];
    if (!bmp_pixels) {
        std::cerr << "内存分配失败（放大图片）" << std::endl;
        close(bmp_fd);
        return;
    }

    if (read(bmp_fd, bmp_pixels, total_pixels_size) != static_cast<ssize_t>(total_pixels_size)) {
        std::cerr << "读取图片像素失败" << std::endl;
        delete[] bmp_pixels;
        close(bmp_fd);
        return;
    }
    close(bmp_fd);

    // -------------------------- 步骤1.5：垂直翻转BMP像素数据 --------------------------
    if (is_bottom_up && bmp_height > 1) { // 只有高度大于1才需要翻转
        char* temp_row = new (std::nothrow) char[bmp_line_bytes];
        if (!temp_row) {
            std::cerr << "翻转行缓冲区分配失败" << std::endl;
            delete[] bmp_pixels;
            close(bmp_fd);
            return;
        }

        for (int row = 0; row < bmp_height / 2; ++row) {
            int opp_row = bmp_height - 1 - row;
            std::memcpy(temp_row, &bmp_pixels[row * bmp_line_bytes], bmp_line_bytes);
            std::memcpy(&bmp_pixels[row * bmp_line_bytes], &bmp_pixels[opp_row * bmp_line_bytes], bmp_line_bytes);
            std::memcpy(&bmp_pixels[opp_row * bmp_line_bytes], temp_row, bmp_line_bytes);
        }

        delete[] temp_row;
    }

    // -------------------------- 步骤2：计算放大参数（中心裁剪） --------------------------
    float scale_x = static_cast<float>(lcd->lcd_width) / bmp_width;
    float scale_y = static_cast<float>(lcd->lcd_height) / bmp_height;
    float scale = std::max(scale_x, scale_y); // 保证填满屏幕

    int crop_width = static_cast<int>(lcd->lcd_width / scale);
    int crop_height = static_cast<int>(lcd->lcd_height / scale);
    int crop_x = (bmp_width - crop_width) / 2;
    int crop_y = (bmp_height - crop_height) / 2;

    // 边界校正
    crop_x = std::max(0, crop_x);
    crop_y = std::max(0, crop_y);
    crop_width = std::min(crop_width, bmp_width - crop_x);
    crop_height = std::min(crop_height, bmp_height - crop_y);

    // -------------------------- 步骤3：最近邻插值放大 --------------------------
    lcd->clearScreen();
    int* lcd_pixels = lcd->mmap_start;

    for (int lcd_y = 0; lcd_y < lcd->lcd_height; ++lcd_y) {
        for (int lcd_x = 0; lcd_x < lcd->lcd_width; ++lcd_x) {
            // 映射到原图坐标
            float src_x = crop_x + static_cast<float>(lcd_x) / scale;
            float src_y = crop_y + static_cast<float>(lcd_y) / scale;

            // 最近邻插值
            int src_x_int = static_cast<int>(std::round(src_x));
            int src_y_int = static_cast<int>(std::round(src_y));

            // 边界限制
            src_x_int = std::max(0, std::min(src_x_int, bmp_width - 1));
            src_y_int = std::max(0, std::min(src_y_int, bmp_height - 1));

            // 计算BMP缓冲区偏移（BGR格式）
            int bmp_offset = src_y_int * bmp_line_bytes + src_x_int * 3;
            if (bmp_offset + 2 >= total_pixels_size) {
                continue; // 越界跳过
            }

            unsigned char blue  = bmp_pixels[bmp_offset];
            unsigned char green = bmp_pixels[bmp_offset + 1];
            unsigned char red   = bmp_pixels[bmp_offset + 2];

            // ARGB 格式写入LCD（假设为32位色深）
            uint32_t argb_color = 0xFF000000u | (red << 16) | (green << 8) | blue;
            size_t lcd_index = static_cast<size_t>(lcd_y) * lcd->lcd_width + lcd_x;

            if (lcd_index < static_cast<size_t>(lcd->lcd_width * lcd->lcd_height)) {
                lcd_pixels[lcd_index] = static_cast<int>(argb_color);
            }
        }
    }

    // ✅ 释放资源
    delete[] bmp_pixels;
}

void Album::displayThumbnailGrid() {
    std::lock_guard<std::mutex> lock(album_mtx);

    // ✅ 安全检查
    if (!has_photos || 
        photo_paths == nullptr || 
        photo_paths->empty() || 
        lcd == nullptr || 
        lcd->mmap_start == nullptr || 
        lcd->mmap_start == (int*)MAP_FAILED) {
        return;
    }

    const int THUMBNAIL_COLS = 4;
    const int THUMBNAIL_ROWS = 2;
    const int MAX_THUMBNAILS = THUMBNAIL_COLS * THUMBNAIL_ROWS; // 8
    const int MARGIN = 10;        // 外边距
    const int SPACING = 8;        // 缩略图之间间距

    // 计算可用区域
    int available_width = lcd->lcd_width - 2 * MARGIN - (THUMBNAIL_COLS - 1) * SPACING;
    int available_height = lcd->lcd_height - 2 * MARGIN - (THUMBNAIL_ROWS - 1) * SPACING;

    int thumb_width = available_width / THUMBNAIL_COLS;
    int thumb_height = available_height / THUMBNAIL_ROWS;

    // 限制最大尺寸（可选）
    thumb_width = std::min(thumb_width, 200);
    thumb_height = std::min(thumb_height, 200);

    // 清屏
    lcd->clearScreen();
    int* lcd_pixels = lcd->mmap_start;

    // 只显示前8张或实际存在的数量
    int num_to_show = std::min(static_cast<int>(photo_paths->size()), MAX_THUMBNAILS);

    for (int i = 0; i < num_to_show; ++i) {
        const std::string& photo_path = (*photo_paths)[i];
        const char* bmp_path = photo_path.c_str();

        // 计算位置
        int col = i % THUMBNAIL_COLS;
        int row = i / THUMBNAIL_COLS;
        int x_offset = MARGIN + col * (thumb_width + SPACING);
        int y_offset = MARGIN + row * (thumb_height + SPACING);

        // 绘制单个缩略图
        drawThumbnailToLcd(bmp_path, lcd_pixels, x_offset, y_offset, thumb_width, thumb_height);
    }
}

void Album::drawThumbnailToLcd(const char* bmp_path, int* lcd_pixels,
                               int x_offset, int y_offset,
                               int thumb_width, int thumb_height) {
    int bmp_fd = open(bmp_path, O_RDONLY);
    if (bmp_fd == -1) {
        std::cerr << "无法打开缩略图: " << bmp_path << std::endl;
        return;
    }

    // 读取 BMP 宽高
    int bmp_width = 0, original_bmp_height = 0;
    if (lseek(bmp_fd, 18, SEEK_SET) == -1 ||
        read(bmp_fd, &bmp_width, 4) != 4 ||
        read(bmp_fd, &original_bmp_height, 4) != 4) {
        close(bmp_fd);
        return;
    }

    int bmp_height = std::abs(original_bmp_height);
    bool is_bottom_up = (original_bmp_height > 0);

    // 计算行对齐
    int pixel_bytes_per_row = bmp_width * 3;
    int bmp_skip = (4 - (pixel_bytes_per_row) % 4) % 4;
    int bmp_line_bytes = pixel_bytes_per_row + bmp_skip;

    // 跳转到像素数据
    if (lseek(bmp_fd, 54, SEEK_SET) == -1) {
        close(bmp_fd);
        return;
    }

    // 读取像素数据
    size_t total_size = static_cast<size_t>(bmp_line_bytes) * bmp_height;
    char* bmp_pixels = new (std::nothrow) char[total_size];
    if (!bmp_pixels || read(bmp_fd, bmp_pixels, total_size) != static_cast<ssize_t>(total_size)) {
        delete[] bmp_pixels;
        close(bmp_fd);
        return;
    }
    close(bmp_fd);

    // 如果是 bottom-up，翻转图像
    if (is_bottom_up && bmp_height > 1) {
        char* temp = new (std::nothrow) char[bmp_line_bytes];
        if (temp) {
            for (int r = 0; r < bmp_height / 2; ++r) {
                int opp_r = bmp_height - 1 - r;
                std::memcpy(temp, &bmp_pixels[r * bmp_line_bytes], bmp_line_bytes);
                std::memcpy(&bmp_pixels[r * bmp_line_bytes], &bmp_pixels[opp_r * bmp_line_bytes], bmp_line_bytes);
                std::memcpy(&bmp_pixels[opp_r * bmp_line_bytes], temp, bmp_line_bytes);
            }
            delete[] temp;
        }
    }

    // 最近邻插值绘制到屏幕
    float scale_x = static_cast<float>(bmp_width) / thumb_width;
    float scale_y = static_cast<float>(bmp_height) / thumb_height;

    for (int ty = 0; ty < thumb_height; ++ty) {
        for (int tx = 0; tx < thumb_width; ++tx) {
            int src_x = static_cast<int>(tx * scale_x);
            int src_y = static_cast<int>(ty * scale_y);

            src_x = std::max(0, std::min(src_x, bmp_width - 1));
            src_y = std::max(0, std::min(src_y, bmp_height - 1));

            int bmp_offset = src_y * bmp_line_bytes + src_x * 3;
            unsigned char blue  = bmp_pixels[bmp_offset];
            unsigned char green = bmp_pixels[bmp_offset + 1];
            unsigned char red   = bmp_pixels[bmp_offset + 2];

            uint32_t argb = 0xFF000000u | (red << 16) | (green << 8) | blue;
            int screen_x = x_offset + tx;
            int screen_y = y_offset + ty;

            if (screen_x >= 0 && screen_x < lcd->lcd_width &&
                screen_y >= 0 && screen_y < lcd->lcd_height) {
                size_t idx = static_cast<size_t>(screen_y) * lcd->lcd_width + screen_x;
                lcd_pixels[idx] = static_cast<int>(argb);
            }
        }
    }

    delete[] bmp_pixels;
}

void Album::displayScaledDownPhoto() {
    std::lock_guard<std::mutex> lock(album_mtx);

    // ✅ 安全检查
    if (!has_photos || 
        photo_paths->empty() || 
        present_photo_index >= photo_paths->size() ||
        lcd == nullptr || 
        lcd->mmap_start == nullptr || 
        lcd->mmap_start == (int*)MAP_FAILED) {
        return;
    }

    const std::string& photo_path = (*photo_paths)[present_photo_index];
    const char* bmp_path = photo_path.c_str();

    int bmp_fd = open(bmp_path, O_RDONLY);
    if (bmp_fd == -1) {
        std::cerr << "打开图片失败: " << strerror(errno) << " (" << bmp_path << ")" << std::endl;
        return;
    }

    // -------------------------- 读取 BMP 信息 --------------------------
    int bmp_width = 0;
    int original_bmp_height = 0;

    if (lseek(bmp_fd, 18, SEEK_SET) == -1 ||
        read(bmp_fd, &bmp_width, 4) != 4 ||
        read(bmp_fd, &original_bmp_height, 4) != 4) {
        std::cerr << "读取 BMP 尺寸失败" << std::endl;
        close(bmp_fd);
        return;
    }

    int bmp_height = std::abs(original_bmp_height);
    bool is_bottom_up = (original_bmp_height > 0);

    // 计算行对齐
    int pixel_bytes_per_row = bmp_width * 3;
    int bmp_skip = (4 - (pixel_bytes_per_row) % 4) % 4;
    int bmp_line_bytes = pixel_bytes_per_row + bmp_skip;
    size_t total_pixels_size = static_cast<size_t>(bmp_line_bytes) * bmp_height;

    // 跳到像素数据
    if (lseek(bmp_fd, 54, SEEK_SET) == -1) {
        std::cerr << "无法定位到像素数据" << std::endl;
        close(bmp_fd);
        return;
    }

    // 读取像素
    char* bmp_pixels = new (std::nothrow) char[total_pixels_size];
    if (!bmp_pixels) {
        std::cerr << "内存分配失败（缩小图片）" << std::endl;
        close(bmp_fd);
        return;
    }

    if (read(bmp_fd, bmp_pixels, total_pixels_size) != static_cast<ssize_t>(total_pixels_size)) {
        std::cerr << "读取像素数据失败" << std::endl;
        delete[] bmp_pixels;
        close(bmp_fd);
        return;
    }
    close(bmp_fd);

    // -------------------------- 垂直翻转（如果需要） --------------------------
    if (is_bottom_up && bmp_height > 1) {
        char* temp_row = new (std::nothrow) char[bmp_line_bytes];
        if (temp_row) {
            for (int row = 0; row < bmp_height / 2; ++row) {
                int opp_row = bmp_height - 1 - row;
                std::memcpy(temp_row, &bmp_pixels[row * bmp_line_bytes], bmp_line_bytes);
                std::memcpy(&bmp_pixels[row * bmp_line_bytes], &bmp_pixels[opp_row * bmp_line_bytes], bmp_line_bytes);
                std::memcpy(&bmp_pixels[opp_row * bmp_line_bytes], temp_row, bmp_line_bytes);
            }
            delete[] temp_row;
        }
    }

    // -------------------------- 计算缩小比例 --------------------------
    float scale_x = static_cast<float>(bmp_width) / lcd->lcd_width;
    float scale_y = static_cast<float>(bmp_height) / lcd->lcd_height;
    float scale = std::max(scale_x, scale_y); // 保证完整显示（留黑边）

    int dst_width = static_cast<int>(bmp_width / scale);
    int dst_height = static_cast<int>(bmp_height / scale);

    // 居中偏移
    int x_offset = (lcd->lcd_width - dst_width) / 2;
    int y_offset = (lcd->lcd_height - dst_height) / 2;

    // -------------------------- 双线性插值绘制 --------------------------
    lcd->clearScreen();
    int* lcd_pixels = lcd->mmap_start;

    for (int dy = 0; dy < dst_height; ++dy) {
        for (int dx = 0; dx < dst_width; ++dx) {
            // 映射回原图坐标（浮点）
            float src_x = dx * scale;
            float src_y = dy * scale;

            // 获取四个最近的像素（双线性插值）
            int x1 = static_cast<int>(std::floor(src_x));
            int y1 = static_cast<int>(std::floor(src_y));
            int x2 = std::min(x1 + 1, bmp_width - 1);
            int y2 = std::min(y1 + 1, bmp_height - 1);

            float fx = src_x - x1;
            float fy = src_y - y1;

            auto get_pixel_color = [&](int x, int y) -> uint32_t {
                int offset = y * bmp_line_bytes + x * 3;
                unsigned char b = bmp_pixels[offset];
                unsigned char g = bmp_pixels[offset + 1];
                unsigned char r = bmp_pixels[offset + 2];
                return 0xFF000000u | (r << 16) | (g << 8) | b;
            };

            uint32_t c11 = get_pixel_color(x1, y1);
            uint32_t c12 = get_pixel_color(x1, y2);
            uint32_t c21 = get_pixel_color(x2, y1);
            uint32_t c22 = get_pixel_color(x2, y2);

            // 插值 R, G, B 分量
            auto interpolate = [](uint8_t c11, uint8_t c12, uint8_t c21, uint8_t c22, 
                                  float fx, float fy) -> uint8_t {
                float top = c11 * (1 - fx) + c21 * fx;
                float bottom = c12 * (1 - fx) + c22 * fx;
                return static_cast<uint8_t>(top * (1 - fy) + bottom * fy);
            };

            uint8_t r = interpolate(
                (c11 >> 16) & 0xFF, (c21 >> 16) & 0xFF,
                (c12 >> 16) & 0xFF, (c22 >> 16) & 0xFF, fx, fy
            );
            uint8_t g = interpolate(
                (c11 >> 8) & 0xFF, (c21 >> 8) & 0xFF,
                (c12 >> 8) & 0xFF, (c22 >> 8) & 0xFF, fx, fy
            );
            uint8_t b = interpolate(
                c11 & 0xFF, c21 & 0xFF,
                c12 & 0xFF, c22 & 0xFF, fx, fy
            );

            uint32_t final_color = 0xFF000000u | (r << 16) | (g << 8) | b;

            int screen_x = x_offset + dx;
            int screen_y = y_offset + dy;

            if (screen_x >= 0 && screen_x < lcd->lcd_width &&
                screen_y >= 0 && screen_y < lcd->lcd_height) {
                size_t idx = static_cast<size_t>(screen_y) * lcd->lcd_width + screen_x;
                lcd_pixels[idx] = static_cast<int>(final_color);
            }
        }
    }

    delete[] bmp_pixels;
}